package wa;

import java.io.*;
import java.util.*;

/**
 * Abstracts a Worship Assistant song database.
 * @author john
 *
 */
public class WADatabase {
	
	private RandomAccessFile index, lyrics;
	private WAFieldDescriptor[] fields;
	private WADataItem[] songs;
	private Map<Integer, String> lyricsByID;
	
	/**
	 * 
	 * @param path		base directory of database
	 */
	public WADatabase(String path) throws IOException {
		index = new RandomAccessFile(path + "/" + WADataParser.INDEX_FILE, "r");
		lyrics = new RandomAccessFile(path + "/" + WADataParser.LYRICS_FILE, "r");
		
		fields = WADataParser.readFieldDescriptors(index);
		songs = WADataParser.readDataItems(index, fields);
		lyricsByID = new HashMap<Integer, String>(songs.length);
		
		// group the lyrics blocks together by ID
		lyrics.seek(WADataParser.LYRICS_BLOCK_LEN);	// skip past header (512 byte block)
		
		StringBuilder sb = new StringBuilder();
		WALyricsBlock wlb = null;
		int curId = -1;
		while ((wlb = WADataParser.readLyricsBlock(lyrics)) != null) {
			if (wlb.id == curId) {
				sb.append(wlb.text);
				System.out.println("--- " + curId + " ---");
				System.out.println(wlb.text);
			}
			else {
				if (sb.length() > 0) {
					lyricsByID.put(curId, sb.toString());
					System.out.println("--- STORE " + curId + " ---");
				}
				curId = wlb.id;
				// append lyrics, if id already exists
				String curLyrics = lyricsByID.get(curId);
				if (curLyrics == null) {
					System.out.println("--- NEW "+ curId + " ---");
					sb = new StringBuilder();
				}
				else {
					System.out.println("--- APPEND "+ curId + " ---");
					sb = new StringBuilder(curLyrics);
				}
				
				sb.append(wlb.text);
				System.out.println(wlb.text);
			}
		}
		
		if (sb.length() > 0) {
			lyricsByID.put(curId, sb.toString());
			System.out.println("--- STORE " + curId + " ---");
		}
	}
	
	public int getNumSongs() {
		return songs.length;
	}
	
	public String getLyrics(int songNo) {
		final int l2Index = getIndex("LYRICS2");
		if (l2Index > 0) {
			Object lyrics2Field = songs[songNo].fields[l2Index];
			return lyricsByID.get(lyrics2Field);
		}
		
		return null;
	}
	
	public Object getField(int songNo, String field) {
		int i = getIndex(field);
		if (i >= 0 && i < WADataParser.NUM_FIELDS)
			return songs[songNo].fields[i];
		
		return null;
	}
	
	/**
	 * Finds the index of the field with the given name.
	 * @param field		data field name
	 * @return	index of the field, or -1 if not found
	 */
	public int getIndex(String field) {
		for (int i=0; i<fields.length; i++)
			if(fields[i].name.equalsIgnoreCase(field))
				return i;
		return -1;
	}
	
	public static void main(String[] args) throws IOException {
		WADatabase db = new WADatabase("data/wa/");
		for (int i=0; i<100; i++) {
			System.out.println("-- SONG " + i + "--");
			System.out.println(db.getLyrics(i));
		}
	}
}
